package mop.gui.main;

import java.text.DateFormat;
import java.util.LinkedList;
import java.util.List;
import javax.swing.JPanel;
import mop.controller.CreateResourceController;
import mop.gui.GUI;
import mop.controller.LoginController;
import mop.controller.MakeResourceReservationController;
import mop.gui.admin.AdminPanel;
import mop.gui.project.ProjectPanel;
import mop.gui.reservation.ReservationPanel;
import mop.gui.resource.ResourcePanel;
import mop.gui.task.TaskPanel;
import mop.gui.task.focuswork.FocusWorkPanel;
import mop.model.World;
import mop.util.event.PropertyChangeEvent;
import mop.util.event.PropertyChangeListener;

/**
 * MainWindow
 * 
 * @author  MOP Team 7
 */
public class MainWindow extends javax.swing.JFrame implements PropertyChangeListener {

    /**
     * Constructor.
     * 
     * @param   GUI
     * @effect  Sets the gui object.
     */
    public MainWindow(GUI gui) {
        initComponents();
        setGui(gui);
        update();
        
        // frame
        this.setVisible(true);
        this.setExtendedState(this.MAXIMIZED_BOTH);
        this.itemDebug.setSelected(gui.getDebug());
    }
    /***************************************************************************
     *                          GUI reference
     ***************************************************************************/

    private GUI gui;

    /**
     * Sets the GUI.
     * 
     * @param   gui
     * @post    gui is set.
     */
    private void setGui(GUI gui) {
        this.gui = gui;
    }

    /**
     * Returns the GUI reference.
     * 
     * @return  this.gui
     */
    public GUI getGui() {
        return this.gui;
    }

    /***************************************************************************
     *                          Necessary controllers
     ***************************************************************************/

    private LoginController loginController;

    /**
     * Adds a controller.
     *
     * @param   createProjectController
     */
    public void addController(LoginController loginController) {
        this.loginController = loginController;
        this.btnLogin.setEnabled(true);
        this.update();
    }

    /***************************************************************************
     *                          Window-specific functionality
     ***************************************************************************/

    private List<JPanel> panels = new LinkedList<JPanel>();
    public AdminPanel adminPanel;
    public FocusWorkPanel focusWorkPanel;
    public ProjectPanel projectPanel;
    public ReservationPanel reservationPanel;
    public ResourcePanel resourcePanel;
    public TaskPanel taskPanel;

    /**
     * Clears the panels from the main window.
     * (used for logging out e.g.)
     */
    public void clearPanels() {
        // Clear them :)
        if (focusWorkPanel != null) focusWorkPanel.clearPanels();
        for (JPanel p : panels) {
            if (p != null) {
                mainPane.remove(p);
                p.removeAll();
                p = null;
            }
        }
        panels.clear();

        adminPanel = null;
        focusWorkPanel = null;
        projectPanel = null;
        reservationPanel = null;
        resourcePanel = null;
        taskPanel = null;
    }

    /**
     * Adds a panel to the main pane.
     */
    public void addAdminPanel() {
        if (adminPanel == null)
            adminPanel = new AdminPanel(gui);
        mainPane.addTab("Admin", adminPanel);
        panels.add(adminPanel);
    }

    /**
     * Adds a panel to the main pane.
     */
    public void addFocusWorkPanel() {
        if (focusWorkPanel == null)
            focusWorkPanel = new FocusWorkPanel(gui);
        mainPane.addTab("Focus Work", focusWorkPanel);
        panels.add(focusWorkPanel);
    }

    /**
     * Adds a panel to the main pane.
     */
    public void addProjectPanel() {
        if (projectPanel == null)
            projectPanel = new ProjectPanel(gui);
        mainPane.addTab("Projects", projectPanel);
        panels.add(projectPanel);
    }

    /**
     * Adds a panel to the main pane.
     */
    public void addReservationPanel(MakeResourceReservationController makeResourceReservationController) {
        if (reservationPanel == null)
            reservationPanel = new ReservationPanel(gui, makeResourceReservationController);
        mainPane.addTab("Reservations", reservationPanel);
        panels.add(reservationPanel);
    }

    /**
     * Adds a panel to the main pane.
     */
    public void addResourcePanel(CreateResourceController createResourceController) {
        if (resourcePanel == null)
            resourcePanel = new ResourcePanel(gui, createResourceController);
        mainPane.addTab("Resources", resourcePanel);
        panels.add(resourcePanel);
    }

    /**
     * Adds a panel to the main pane.
     */
    public void addTaskPanel() {
        if (taskPanel == null)
            taskPanel = new TaskPanel(gui);
        mainPane.addTab("Tasks", taskPanel);
        panels.add(taskPanel);
    }

    /**
     * Updates everything in MainWindow.
     */
    public void update() {
        // Show current user.
        try {
            String currentUser = loginController.getCurrentUser().getDescription();
            this.lblCurrentUser.setText("Current User: " + currentUser);
        } catch (Throwable t) {
            this.lblCurrentUser.setText("Not logged in!");
        }

        // Show system time.
        DateFormat dateTimeFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT);
        lblSysTime.setText("System Time (since last update): " + dateTimeFormat.format(World.getTime()));

        // Update panels.
        if (focusWorkPanel != null) focusWorkPanel.update();
        if (projectPanel != null) projectPanel.update();
        if (reservationPanel != null) reservationPanel.update();
        if (resourcePanel != null) resourcePanel.update();
        if (taskPanel != null) taskPanel.update();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        mainPane = new javax.swing.JTabbedPane();
        tabMain = new javax.swing.JPanel();
        lblTitle = new javax.swing.JLabel();
        lblCredits = new javax.swing.JLabel();
        btnLogin = new javax.swing.JButton();
        lblCurrentUser = new javax.swing.JLabel();
        lblSysTime = new javax.swing.JLabel();
        mainMenuBar = new javax.swing.JMenuBar();
        menuFile = new javax.swing.JMenu();
        itemQuit = new javax.swing.JMenuItem();
        menuHelp = new javax.swing.JMenu();
        itemDebug = new javax.swing.JCheckBoxMenuItem();
        itemForceUpdate = new javax.swing.JMenuItem();
        javax.swing.JMenu jMenu1 = new javax.swing.JMenu();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("MOP Project"); // NOI18N
        setName("Form"); // NOI18N

        mainPane.setName("mainPane"); // NOI18N

        tabMain.setName("tabMain"); // NOI18N
        tabMain.setLayout(new java.awt.GridBagLayout());

        lblTitle.setFont(new java.awt.Font("Tahoma", 1, 14));
        lblTitle.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        lblTitle.setText("MOP Project 2009-2010 - Iteratie 3");
        lblTitle.setName("lblTitle"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL;
        gridBagConstraints.ipady = 40;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
        gridBagConstraints.insets = new java.awt.Insets(-25, 4, 0, 4);
        tabMain.add(lblTitle, gridBagConstraints);

        lblCredits.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        lblCredits.setText("<html> Adriaan Larmuseau<br>  Laurens Van Keer<br> Seba Kerckhof<br> </html>"); // NOI18N
        lblCredits.setName("lblCredits"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.ipadx = 23;
        gridBagConstraints.ipady = 40;
        tabMain.add(lblCredits, gridBagConstraints);

        btnLogin.setText("Log In");
        btnLogin.setEnabled(false);
        btnLogin.setName("btnLogin"); // NOI18N
        btnLogin.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnLoginActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.ipadx = 16;
        gridBagConstraints.insets = new java.awt.Insets(21, 0, 1, 0);
        tabMain.add(btnLogin, gridBagConstraints);

        mainPane.addTab("Main", tabMain);

        lblCurrentUser.setText("Current User:"); // NOI18N
        lblCurrentUser.setName("lblCurrentUser"); // NOI18N

        lblSysTime.setFont(new java.awt.Font("Tahoma", 2, 11)); // NOI18N
        lblSysTime.setText("System Time (since last update): ");
        lblSysTime.setName("lblSysTime"); // NOI18N

        mainMenuBar.setName("mainMenuBar"); // NOI18N

        menuFile.setText("File"); // NOI18N
        menuFile.setName("menuFile"); // NOI18N

        itemQuit.setText("Quit"); // NOI18N
        itemQuit.setName("itemQuit"); // NOI18N
        itemQuit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                itemQuitActionPerformed(evt);
            }
        });
        menuFile.add(itemQuit);

        mainMenuBar.add(menuFile);

        menuHelp.setText("Help"); // NOI18N
        menuHelp.setName("menuHelp"); // NOI18N

        itemDebug.setSelected(true);
        itemDebug.setText("Debug Mode");
        itemDebug.setName("itemDebug"); // NOI18N
        itemDebug.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                itemDebugActionPerformed(evt);
            }
        });
        menuHelp.add(itemDebug);

        itemForceUpdate.setText("Force update tables");
        itemForceUpdate.setName("itemForceUpdate"); // NOI18N
        itemForceUpdate.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                itemForceUpdateActionPerformed(evt);
            }
        });
        menuHelp.add(itemForceUpdate);

        mainMenuBar.add(menuHelp);

        jMenu1.setName("jMenu1"); // NOI18N
        mainMenuBar.add(jMenu1);

        setJMenuBar(mainMenuBar);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(mainPane, javax.swing.GroupLayout.DEFAULT_SIZE, 508, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(lblCurrentUser)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 283, Short.MAX_VALUE)
                        .addComponent(lblSysTime)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(mainPane, javax.swing.GroupLayout.DEFAULT_SIZE, 513, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lblCurrentUser)
                    .addComponent(lblSysTime))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    /**
     * Forces an update of all tables.
     *
     * @param   evt
     */
private void itemForceUpdateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_itemForceUpdateActionPerformed
    this.update();
}//GEN-LAST:event_itemForceUpdateActionPerformed

    /**
     * Closes the application.
     * @param   evt
     */
private void itemQuitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_itemQuitActionPerformed
    System.exit(0);
}//GEN-LAST:event_itemQuitActionPerformed

    /**
     * Opens the ChangeClockDialog.
     *
     * @param   evt
     */
private void btnLoginActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLoginActionPerformed
    (new LoginDialog(gui, this.loginController)).setVisible(true);
}//GEN-LAST:event_btnLoginActionPerformed

private void itemDebugActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_itemDebugActionPerformed
    gui.setDebug(this.itemDebug.isSelected());
}//GEN-LAST:event_itemDebugActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnLogin;
    private javax.swing.JCheckBoxMenuItem itemDebug;
    private javax.swing.JMenuItem itemForceUpdate;
    private javax.swing.JMenuItem itemQuit;
    private javax.swing.JLabel lblCredits;
    private javax.swing.JLabel lblCurrentUser;
    private javax.swing.JLabel lblSysTime;
    private javax.swing.JLabel lblTitle;
    private javax.swing.JMenuBar mainMenuBar;
    private javax.swing.JTabbedPane mainPane;
    private javax.swing.JMenu menuFile;
    private javax.swing.JMenu menuHelp;
    private javax.swing.JPanel tabMain;
    // End of variables declaration//GEN-END:variables

    /**
     * Handles property changes from model.
     * 
     * @param   PropertyChangeEvent
     */
    public void handlePropertyChange(PropertyChangeEvent e) {
        this.update();
    }
}